<?php

namespace App\Http\Controllers\Cruise\Web;

use App\Http\Controllers\BaseController;
use App\Http\Middleware\OpenShop\UserPermissionAuth;
use App\Http\Validate\Cruise\CruiseProjectValidate;
use App\Models\Cruise\CruiseTaskProjectModel;
use App\Service\BaseService;
use App\Service\Cruise\CruiseProject\CruiseBaseService;
use App\Service\Cruise\CruiseProject\CruiseProjectParam;
use App\Service\Cruise\CruiseProject\CruiseProjectService;
use App\Support\CustomForm\AttributeCruiseSupport;
use App\Support\CustomForm\AttributeSupport;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class CruiseProjectController extends BaseController
{
    private CruiseProjectParam $param;

    public function __construct(Request $request)
    {
        $categoryId       = (int)$request->get('categoryId');
        $name             = (string)$request->get('name');
        $tipsType         = (string)$request->get('tipsType');
        $tipsContent      = (string)$request->get('tipsContent');
        $tipsResource     = (array)$request->get('tipsResource');
        $status           = (int)$request->get('status');
        $inputType        = (string)$request->get('inputType');
        $maxContentLength = (int)$request->get('maxContentLength');
        $options          = $request->get('options') ? (array)$request->get('options') : [];
        $required         = (bool)$request->get('required');
        $meanType         = (int)$request->get('meanType');
        $richShow         = (string)$request->get('richShow');
        $pageSize         = (int)$request->get('pageSize', 20);
        $pageNum          = (int)$request->get('pageNum', 1);

        $this->param = (new CruiseProjectParam())->setCategoryId($categoryId)
                                                 ->setName($name)
                                                 ->setTipsType($tipsType)
                                                 ->setTipsContent($tipsContent)
                                                 ->setTipsResource($tipsResource)
                                                 ->setStatus($status)
                                                 ->setInputType($inputType)
                                                 ->setMaxContentLength($maxContentLength)
                                                 ->setOptions($options)
                                                 ->setRequired($required)
                                                 ->setMeanType($meanType)
                                                 ->setRichShow($richShow)
                                                 ->setPageSize($pageSize)
                                                 ->setPageNum($pageNum);
    }

    private function addValidate(Request $request)
    {
        $this->validate($request, [
            'categoryId'       => 'required|integer',
            'name'             => 'required|string',
            'tipsType'         => ['string', Rule::in(CruiseTaskProjectModel::TIPS_TYPES)],
            'tipsContent'      => 'string',
            "tipsResource"     => 'array',
            'status'           => 'required|integer|between:0,1',
            'inputType'        => ['required', 'string', Rule::in(CruiseTaskProjectModel::INPUT_TYPES)],
            'maxContentLength' => 'integer|min:0',
            'options'          => ['array', Rule::requiredIf(function () use ($request) {
                return in_array($request->get('inputType', ''), array_merge(AttributeCruiseSupport::CRUISE_CHECK_MODULE, [AttributeSupport::INPUT_TYPE_SELECT]));
            })],
            'options.*.text'   => [Rule::requiredIf(function () use ($request) {
                return in_array($request->get('inputType', ''), array_merge(AttributeCruiseSupport::CRUISE_CHECK_MODULE, [AttributeSupport::INPUT_TYPE_SELECT]));
            })],
            'options.*.value'  => [Rule::requiredIf(function () use ($request) {
                return in_array($request->get('inputType', ''), array_merge(AttributeCruiseSupport::CRUISE_CHECK_MODULE, [AttributeSupport::INPUT_TYPE_SELECT]));
            })],
            'options.*.score'  => ['integer', Rule::requiredIf(function () use ($request) {
                return in_array($request->get('inputType', ''), AttributeCruiseSupport::CRUISE_CHECK_MODULE);
            })],
            'options.*.remark' => 'string',
            'required'         => 'required|bool',
            'richShow'         => 'string',
        ], [
            'options.*.score.required' => '巡检项的分数不能为空'
        ]);

        // 平铺提示。文字、图片二选一
        if ($request->get('tipsType', '') == AttributeSupport::INPUT_TYPE_STRING_IMG_GROUP) {
            if (empty($request->get('tipsContent')) && empty($request->get('tipsResource'))) {
                BaseService::throwErr("文字内容和上传图片至少选一个");
            }
        }
    }

    public function add(Request $request): JsonResponse
    {
        $this->addValidate($request);

        return $this->success(['id' => (new CruiseProjectService())->addOrEdit($this->param, 0)]);
    }

    public function edit(Request $request, int $id): JsonResponse
    {
        $this->addValidate($request);

        return $this->success(['id' => (new CruiseProjectService())->addOrEdit($this->param, $id)]);
    }

    public function offline(Request $request, int $id): JsonResponse
    {
        $request->merge(['id' => $id]);

        $this->validate($request, [
            'id'     => 'required|integer|min:0',
            'status' => 'required|integer|between:0,1',
        ]);

        (new CruiseProjectService())->offline($this->param, $id);

        return $this->success();
    }

    public function delete(Request $request, int $id): JsonResponse
    {
        $request->merge(['id' => $id]);

        $this->validate($request, [
            'id' => 'required|integer|min:0',
        ]);

        (new CruiseProjectService())->delete($id);

        return $this->success();
    }

    public function lists(Request $request): JsonResponse
    {
        $types = CruiseBaseService::getPermissionTypes(getRmsUserPermissionList([], UserPermissionAuth::MODULE_CRUISE));

        return $this->success((new CruiseProjectService())->lists($this->param, $types));
    }

    public function detail(Request $request, int $id): JsonResponse
    {
        return $this->success((new CruiseProjectService())->detail($id));
    }

    public function meanTypes(Request $request): JsonResponse
    {
        return $this->success(collect(CruiseTaskProjectModel::MEAN_TYPE_TEXT)->map(function ($v, $k) {
            return [
                'text'    => $v,
                'value'   => $k,
                'modules' => CruiseTaskProjectModel::MEAN_TYPE_RELATION_MODULE[$k] ?? [],
            ];
        })->values()->toArray());
    }
}
